

#ifndef __CE_TERRAINMESH_H__
#define __CE_TERRAINMESH_H__

#include <cegfx/ce.h>
#include <cegfx/ceexport.h>
#include <cegfx/igeometry.h>
#include <cegfx/ilodsolver.h>

class CE_GFX_API ceTerrainMesh : public iGeometry
{
	IQF_DECLARATION;
private:
	ceBoundingBox	bbox;

	LPDIRECT3DVERTEXDECLARATION9		vertexDeclaration;
	unsigned stride;

	LPDIRECT3DVERTEXBUFFER9					vertexBuffer;
	unsigned												numVertices;

	struct Patch
	{
		LPDIRECT3DINDEXBUFFER9					indexBuffer;
		unsigned												numTriangles;
		ceBoundingBox										bbox;

		unsigned												x0;
		unsigned												z0;
		unsigned												offset;
		unsigned												llhOffset;
		unsigned												llvOffset;
		unsigned												step;
		bool														highRes;
	};

	struct Vertex
	{
		float x, y, z;
		float nx, ny, nz;
		float tu, tv;
	};

	Vertex*														vertices;

	Patch*														patches;
	unsigned													numPatches;

	TerrainSize												ts;
	TerrainPatchSize									tps;

	iLODSolver*												solver;

	void UpdatePatchDimensions (Patch* patch);
	bool UpdatePatchIndices (Patch* patch);

public:
	ceTerrainMesh ();
	~ceTerrainMesh ();

	void SetLODSolver (iLODSolver* solver);
	iLODSolver* GetLODSolver ();
	const iLODSolver* GetLODSolver () const;

	bool Initialize (LPDIRECT3DDEVICE9 device, const float* heights, float size, TerrainSize ts, TerrainPatchSize tps);

	virtual void Render (const ceRenderEnv& env);

	virtual void Update (const ceUpdateEnv& env);

	virtual const ceBoundingBox& GetBoundingBox () const;

	/**
	 * \brief Returns the local position at (x, y)
	 * \param x The x coordinate [0, 1]
	 * \param y The y coordinate [0, 1]
	 * \return The location position at (x, y)
	 */
	virtual D3DXVECTOR3 GetPosition (float x, float y) const;

	/**
	 * \brief Returns the local position of the node at (x, y)
	 * \param x 
	 * \param y
	 * \return The local position of the node at (x, y)
	 */
	virtual D3DXVECTOR3 GetVertexPosition (unsigned x, unsigned y) const;

};


#endif /* ! __CE_TERRAINMESH_H__ */ 
